package com.denlaku.longan.service.impl;

import com.denlaku.longan.BizModule;
import com.denlaku.longan.anno.RequiredTx;
import com.denlaku.longan.qo.MyCollectQuery;
import com.denlaku.longan.qo.Query;
import com.denlaku.longan.repository.MyCollectRepository;
import com.denlaku.longan.service.DashboardService;
import com.denlaku.longan.service.MyCollectService;
import com.denlaku.longan.util.Lists;
import com.denlaku.longan.util.Objects;
import com.denlaku.longan.util.ParallelUtil;
import com.denlaku.longan.util.SnowflakeUtils;
import com.denlaku.longan.vo.Dashboard;
import com.denlaku.longan.vo.MyCollect;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author tianx
 */
@Service
public class MyCollectServiceImpl implements MyCollectService {
    @Autowired
    private MyCollectRepository myCollectRepository;

    @Autowired
    private DashboardService dashboardService;

    @Override
    @RequiredTx
    public void add(MyCollect myCollect) {
        myCollect.setId(SnowflakeUtils.nextId());
        myCollectRepository.add(myCollect);
    }

    @Override
    @RequiredTx
    public void delete(MyCollectQuery query) {
        myCollectRepository.delete(query);
    }

    @Override
    @RequiredTx
    public void deleteByUid(Long uid) {
        myCollectRepository.deleteByUid(uid);
    }

    @Override
    public List<MyCollect> list(MyCollectQuery query) {
        List<MyCollect> list = myCollectRepository.list(query);
        processCollects(list);
        return list;
    }

    private void processCollects(List<MyCollect> collects) {
        Map<String, List<MyCollect>> collectGroups = ListUtils.emptyIfNull(collects).stream()
                .collect(Collectors.groupingBy(MyCollect::getBiz));
        List<Runnable> tasks = Lists.ofSize(collectGroups.size());
        List<MyCollect> dashboardCollects = collectGroups.getOrDefault(BizModule.DASHBOARD, Collections.emptyList());
        tasks.add(() -> processDashboardCollects(dashboardCollects));
        ParallelUtil.execute(tasks);
    }

    private void processDashboardCollects(List<MyCollect> collects) {
        List<Runnable> tasks = Lists.ofSize(collects.size());
        for (MyCollect collect : collects) {
            tasks.add(() -> {
                Dashboard dashboard = dashboardService.get(Query.of(collect.getTenantId(), collect.getDataId()));
                Objects.ifPresent(dashboard, () -> {
                    collect.setTitle(dashboard.getTitle());
                    collect.setDesc(dashboard.getDesc());
                });
            });
        }
        ParallelUtil.execute(tasks);
    }

    /**
     * 判断是否收藏
     *
     * @param query 查询参数
     * @return 是否收藏
     */
    @Override
    @RequiredTx
    public boolean collected(MyCollectQuery query) {
        return myCollectRepository.collected(query);
    }

}
